home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / Libraries / VideoToolbox 96.06.15 / VideoToolboxSources / PlotXY.c < prev    next >
Text File  |  1994-08-01  |  4KB  |  154 lines

  1. /* PlotXY.c
  2. Copyright © 1991 Denis G. Pelli
  3. PlotXY plots graphs, one point at a time, possibly interleaving multiple graphs. 
  4. The user keeps a PlotXYStyle structure associated with each curve, which allows
  5. interleaving of points for several curves, which is essential for online monitoring.
  6.  
  7. // defined in VideoToolbox.h
  8. typedef struct{
  9.     Boolean continuing;    // zero to start a new curve
  10.     long color;            // e.g. blackColor, blueColor
  11.     short lineWidth;    // in pixels, zero for none
  12.     short symbolWidth;    // in pixels, zero for none
  13.     short dashOffset;    // in pixels
  14.     short dash[5];        // in pixels. The array is terminated by a zero element
  15.     short h,v;            // reserved for internal use
  16.     Fixed pathLengthF;    // reserved for internal use
  17. } PlotXYStyle;
  18.  
  19. WARNING: I've discovered that this routine may crash if fed garbage x,y coordinates
  20. while dashing is on, e.g. extremely large numbers. I'm not sure where the problem is. 
  21. Overflows shouldn't cause crashes.
  22.  
  23. HISTORY:
  24. 90         dgp wrote it.
  25. 3/91    dgp    re-rewrote it, adding dashing and symbols, and making it re-entrant.
  26. 3/18/91    dgp    replaced floating point math by fixed point math.
  27.             made compatible with original quickdraw.
  28. 8/24/91    dgp    Made compatible with THINK C 5.0.
  29. 12/27/91 dgp Made dashing faster by measuring path length modulo the dashing period.
  30. 1/25/93 dgp removed obsolete support for THINK C 4.
  31. 5/28/94 dgp Changed the second argument of FillOval() to be "&blackPattern" instead of 
  32. "blackPattern" for compatibility with Apple's redefinition of Pattern as a struct 
  33. instead of an array. This makes the call compatible with Apple's Universal Headers.
  34. 5/31/94    dgp    added (ConstPatternParam) cast to above, to retain compatibility
  35. with the old definition of Pattern.
  36. */
  37. #include "VideoToolbox.h"
  38.  
  39. Fixed HypotenuseF(long base,long height);
  40.  
  41. Fixed HypotenuseF(long base,long height)
  42. {
  43.     base*=base;
  44.     height*=height;
  45.     return FracSqrt(base+height)<<1;
  46. }
  47.  
  48. void PlotXY(WindowPtr window,double x,double y,PlotXYStyle *style)
  49. /*
  50. Draws line to point x,y, where window is mapped as a unit square, with origin
  51. at lower left. 
  52. */
  53. {
  54.     register PlotXYStyle *s;
  55.     register int i;
  56.     register short h,v,dh,dv;
  57.     Rect r;
  58.     WindowPtr oldPort;
  59.     PenState penState;
  60.     Pattern blackPattern={-1,-1,-1,-1,-1,-1,-1,-1};
  61.     Boolean dashOn;
  62.     int dashElements;
  63.     int dashDebit;
  64.     int length,delta;
  65.     Fixed lengthF;
  66.     long oldColor;
  67.     int dashingPeriod;
  68.     
  69.     s=style;
  70.     GetPort(&oldPort);
  71.     SetPort(window);
  72.     BringToFront(window);
  73.     GetPenState(&penState);
  74.     oldColor=window->fgColor;
  75.     ForeColor(s->color);
  76.     PenSize(s->lineWidth,s->lineWidth);
  77.     r=window->portRect;
  78.     h=(r.right-r.left)*x;
  79.     v=(r.bottom-r.top)*(1.0-y);
  80.     
  81.     if(!s->continuing){
  82.         /* First point, just go there */
  83.         s->pathLengthF=s->dashOffset<<16;
  84.         s->h=h;
  85.         s->v=v;
  86.         MoveTo(s->h,s->v);
  87.         s->continuing=1;
  88.     }
  89.     else {
  90.         /* Not first point, start from previous point */
  91.         MoveTo(s->h,s->v);
  92.         h-=s->h;
  93.         v-=s->v;
  94.         s->h+=h;
  95.         s->v+=v;
  96.         lengthF=HypotenuseF(h,v);
  97.         length=lengthF>>16;
  98.         /* Figure out where we are in dashing sequence */
  99.         dashDebit=s->pathLengthF>>16;
  100.         dashOn=1;
  101.         dashingPeriod=0;
  102.         for(i=0;s->dash[i]>0;i++)dashingPeriod+=s->dash[i];
  103.         dashElements=i;
  104.         if(dashElements%2==1)dashingPeriod*=2;
  105.         if(dashingPeriod==0)dashingPeriod=1;    /* to avoid divide by zero */
  106.         if(dashElements==0){
  107.             Line(h,v);
  108.         }
  109.         else {
  110.             for(i=0;;i++){
  111.                 i%=dashElements;
  112.                 dashDebit-=s->dash[i];
  113.                 if(dashDebit<0){
  114.                     dashDebit+=s->dash[i];
  115.                     break;
  116.                 }
  117.                 dashOn=!dashOn;
  118.             }
  119.             /* Draw dashed line */
  120.             for(;;i++){
  121.                 i%=dashElements;
  122.                 if(length<=s->dash[i]-dashDebit){
  123.                     if(dashOn)Line(h,v);
  124.                     else Move(h,v);
  125.                     dashDebit+=length;
  126.                     break;
  127.                 }
  128.                 delta=s->dash[i]-dashDebit;
  129.                 dh=((long)h*delta+length/2)/length;
  130.                 dv=((long)v*delta+length/2)/length;
  131.                 if(dashOn)Line(dh,dv);
  132.                 else Move(dh,dv);
  133.                 h-=dh;
  134.                 v-=dv;
  135.                 length-=delta;
  136.                 dashDebit=0;
  137.                 dashOn=!dashOn;
  138.             }
  139.         }
  140.         lengthF%=(long)dashingPeriod<<16;        /* reduce mod period to avoid overflow */
  141.         s->pathLengthF+=lengthF;
  142.         s->pathLengthF%=(long)dashingPeriod<<16;/* reduce mod period for speed */
  143.     }
  144.     
  145.     /* Draw symbol */
  146.     SetRect(&r,0,0,s->symbolWidth,s->symbolWidth);
  147.     OffsetRect(&r,-r.right/2,-r.bottom/2);
  148.     OffsetRect(&r,s->h,s->v);
  149.     FillOval(&r,(ConstPatternParam)&blackPattern);    // compatible with Apple's Universal Headers
  150.     ForeColor(oldColor);
  151.     SetPenState(&penState);
  152.     SetPort(oldPort);
  153. }
  154.